/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.chart.dial;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import twaver.AlarmSeverity;
import twaver.Element;
import twaver.Node;
import twaver.TDataBox;
import twaver.TUIManager;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.chart.DialChart;
import twaver.chart.Marker;
import twaver.swing.TExpandPane;
import twaver.swing.TableLayout;
import demo.DemoPane;

public class DialChartDemo extends DemoPane {

	private TDataBox box = new TDataBox();
	private DialChart wholeChart = new DialChart(box) {
		public Color getColor(Element element) {
			if (this.getMarkers() != null && this.getMarkers().size() > 0) {
				double value = element.getChartValue();
				int index = (int) (value / 20);
				return markerColors[index];
			} else {
				return super.getColor(element);
			}
		}
	};
	private DialChart arcChart = new DialChart(box);
	private Color[] markerColors = {    AlarmSeverity.COLOR_CLEARED,
										AlarmSeverity.COLOR_INDETERMINATE, 
										AlarmSeverity.COLOR_WARNING,
										AlarmSeverity.COLOR_MINOR,
										AlarmSeverity.COLOR_MAJOR,
										AlarmSeverity.COLOR_CRITICAL,
										AlarmSeverity.COLOR_CRITICAL};
	private List markers = null;
	private Element element;
	private boolean isplus = true;

	public DialChartDemo() {
		initBox();
		setWholeChartAttribute();
		setArcChartAttribute();
		setMarker(true);
		initGUI();

		Thread thread = new Thread() {
			public void run() {
				while (true) {
					try {
						if(wholeChart.isShowing()){
							changeElementValue();
						}
						Thread.sleep(100);
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}
		};
		thread.start();
	}

	private void initBox() {
		element = new Node();
		element.setName("Element");
		element.putChartDialHandLength(0.9);
		element.putChartDialHandStyle(TWaverConst.DIAL_HAND_STYLE_TRIANGLE);
		element.putChartValue(wholeChart.getMinValue() + (wholeChart.getMaxValue() - wholeChart.getMinValue()) / 4);
		element.putChartColor(Color.LIGHT_GRAY);
		element.putChartStroke(TWaverConst.STROKE_ZIGZAG_MIDDLE);
		box.addElement(element);
	}

	private void setWholeChartAttribute() {
		wholeChart.setMaxValue(120);
		wholeChart.setScaleMajorCount(12);
		wholeChart.setValueTextCenter(true);
		wholeChart.setValueTextColor(Color.ORANGE);
		wholeChart.setScaleInside(true);
		wholeChart.setScaleTextFont(TUIManager.getDefaultPlainFont());
		wholeChart.setValueTextFont(TUIManager.getDefaultPlainFont());
		wholeChart.setBackgroundVisible(true);
		wholeChart.setBackgroundOutlineColor(null);
		wholeChart.setBackgroundGradient(true);
		wholeChart.setBackgroundFillColor(Color.DARK_GRAY);
		wholeChart.getLegendPane().setVisible(false);
	}

	private void setArcChartAttribute() {
		arcChart.setMaxValue(120);
		arcChart.setScaleMajorCount(12);
		arcChart.setBackgroundVisible(true);
		arcChart.setBackgroundGradient(true);
		arcChart.setBackgroundOutlineColor(null);
		arcChart.setBackgroundFillColor(Color.DARK_GRAY);
		arcChart.getLegendPane().setVisible(false);

		arcChart.setDialType(TWaverConst.DIAL_TYPE_ARC);
		arcChart.setScaleInside(true);
		arcChart.setScaleTextFont(TUIManager.getDefaultPlainFont());
		arcChart.setValueTextFont(TUIManager.getDefaultPlainFont());
		arcChart.setValueTextCenter(true);
		arcChart.setValueTextColor(Color.RED);
		arcChart.setScaleMinTextVisible(true);
	}

	private void setMarker(boolean isAdd) {
		if (!isAdd) {
			wholeChart.setMarkers(null);
			arcChart.setMarkers(null);
			return;
		}
		if (markers == null) {
			markers = new ArrayList();
			for (int i = 0; i < 7; i++) {
				Marker marker = new Marker(i * 20, markerColors[i]);
				markers.add(marker);
			}
		}
		wholeChart.setMarkers(markers);
	}

	private void initGUI() {
		JPanel wholePanel = new JPanel(new BorderLayout());
		wholePanel.setBorder(BorderFactory.createTitledBorder("Whole"));
		TExpandPane expandPane = new TExpandPane(createWholeControlPanel(), TExpandPane.SOUTH, true, false);
		wholePanel.add(wholeChart, BorderLayout.CENTER);
		wholePanel.add(expandPane, BorderLayout.SOUTH);

		JPanel arcPanel = new JPanel(new BorderLayout());
		arcPanel.setBorder(BorderFactory.createTitledBorder("Arc"));
		expandPane = new TExpandPane(createArcControlPanel(), TExpandPane.SOUTH, true, false);
		arcPanel.add(arcChart, BorderLayout.CENTER);
		arcPanel.add(expandPane, BorderLayout.SOUTH);

		GridLayout layout = new GridLayout();
		layout.setRows(2);
		layout.setColumns(1);
		layout.setHgap(3);
		layout.setVgap(3);
		JPanel rightPanel = new JPanel(layout);
		rightPanel.add(wholePanel);
		rightPanel.add(arcPanel);

		JPanel leftPanel = new JPanel(new TableLayout(new double[] { TableLayout.FILL }, new double[] { TableLayout.PREFERRED, TableLayout.FILL }, 5, 10));
		leftPanel.add(createControlPanel(), "0,0,0,0");
		leftPanel.add(createElementControlPanel(), "0,1,0,1");
		JSplitPane splitPane = new JSplitPane();
		splitPane.setLeftComponent(leftPanel);
		splitPane.setRightComponent(rightPanel);
		splitPane.setDividerLocation(300);

		this.setLayout(new BorderLayout());
		this.add(splitPane, BorderLayout.CENTER);
	}

	public JPanel createWholeControlPanel() {
		double[] rows = new double[2];
		for (int i = 0; i < rows.length; i++) {
			rows[i] = TableLayout.PREFERRED;
		}
		double[] cols = new double[] { TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED };
		JPanel panel = new JPanel(new TableLayout(cols, rows, 5, 5));
		initSliderPanel(panel, "StartAngle:", 0, wholeChart.getStartAngle(), 0, 180, false);
		initSliderPanel(panel, "EndAngle:", 1, wholeChart.getEndAngle(), 180, 360, false);

		return panel;
	}

	public JPanel createArcControlPanel() {
		double[] rows = new double[] { TableLayout.PREFERRED };
		double[] cols = new double[] { TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED };
		JPanel panel = new JPanel(new TableLayout(cols, rows, 5, 5));
		initSliderPanel(panel, "ArcRange:", 0, arcChart.getArcRange(), 0, 360, false);

		return panel;
	}

	public void initSliderPanel(JPanel panel, final String text, int index, double value, double min, double max, final boolean isPercent) {
		panel.add(createJLabel(text), "0," + index + ",0," + index);
		final JTextField textfield = createJTextField();
		final JSlider slider = createSlider((int) min, (int) max);
		slider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				int sliderValue = slider.getValue();
				if (text.equals("MaxValue:")) {
					wholeChart.setMaxValue(sliderValue);
					arcChart.setMaxValue(sliderValue);
				}
				else if (text.equals("MinValue:")) {
					wholeChart.setMinValue(sliderValue);
					arcChart.setMinValue(sliderValue);
				}
				else if (text.equals("Scale Minor Count:")) {
					wholeChart.setScaleMinorCount(sliderValue);
					arcChart.setScaleMinorCount(sliderValue);
				}
				else if (text.equals("Scale Major Count:")) {
					wholeChart.setScaleMajorCount(sliderValue);
					arcChart.setScaleMajorCount(sliderValue);
				}
				else if (text.equals("Scale Length:")) {
					wholeChart.setScaleLength(sliderValue);
					arcChart.setScaleLength(sliderValue);
				}
				else if (text.equals("Ball Percent Size:")) {
					wholeChart.setBallPercentSize(sliderValue / 100.0);
					arcChart.setBallPercentSize(sliderValue / 100.0);
				}
				else if (text.equals("StartAngle:")) {
					wholeChart.setStartAngle(slider.getValue());
				}
				else if (text.equals("EndAngle:")) {
					wholeChart.setEndAngle(slider.getValue());
				}
				else if (text.equals("ArcRange:")) {
					arcChart.setArcRange(slider.getValue());
				}

				if (isPercent) {
					textfield.setText(sliderValue + "%");
				}
				else {
					textfield.setText(sliderValue + "");
				}
			}
		});
		slider.setValue(-1);
		slider.setValue((int) value);
		panel.add(slider, "1," + index + ",1," + index);
		panel.add(textfield, "2," + index + ",2," + index);
	}

	public JPanel createControlPanel() {
		double[] rows = new double[8];
		for (int i = 0; i < rows.length; i++) {
			rows[i] = TableLayout.PREFERRED;
		}
		double[] cols = new double[] { TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED };
		JPanel panel = new JPanel(new TableLayout(cols, rows, 5, 10));
		panel.setBorder(BorderFactory.createTitledBorder("Chart Style"));

		List titles = new ArrayList();
		titles.add("MaxValue:");
		titles.add("MinValue:");
		titles.add("Scale Minor Count:");
		titles.add("Scale Major Count:");
		titles.add("Scale Length:");
		titles.add("Ball Percent Size:");
		List values = new ArrayList();
		values.add(new Double(wholeChart.getMaxValue()));
		values.add(new Double(wholeChart.getMinValue()));
		values.add(new Double(wholeChart.getScaleMinorCount()));
		values.add(new Double(wholeChart.getScaleMajorCount()));
		values.add(new Double(wholeChart.getScaleLength()));
		values.add(new Double(wholeChart.getBallPercentSize() * 100));
		double[][] rangle = new double[][] { { 60, 120 }, { 0, 60 }, { 0, 10 }, { 0, 20 }, { 0, 30 }, { 0, 100 } };
		int rowIndex = 0;
		int size = titles.size();
		for (int i = 0; i < size; i++) {
			if (i == size - 1) {
				initSliderPanel(panel, titles.get(i).toString(), rowIndex, ((Double) (values.get(i))).doubleValue(), rangle[i][0], rangle[i][1], true);
			}
			else {
				initSliderPanel(panel, titles.get(i).toString(), rowIndex, ((Double) (values.get(i))).doubleValue(), rangle[i][0], rangle[i][1], false);
			}
			rowIndex++;
		}

		rows = new double[3];
		for (int i = 0; i < rows.length; i++) {
			rows[i] = TableLayout.PREFERRED;
		}
		cols = new double[] { TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED };
		JPanel stylePanel = new JPanel(new TableLayout(cols, rows, 10, 10));

		stylePanel.add(createJLabel("Scale Style:"), "0," + 0 + ",0," + 0);
		final JComboBox scaleSytle = new JComboBox();
		scaleSytle.addItem("Line");
		scaleSytle.addItem("Ball");
		scaleSytle.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (scaleSytle.getSelectedItem().toString().equals("Ball")) {
					wholeChart.setScaleStyle(TWaverConst.DIAL_SCALE_STYLE_BALL);
					arcChart.setScaleStyle(TWaverConst.DIAL_SCALE_STYLE_BALL);
				}
				else {
					wholeChart.setScaleStyle(TWaverConst.DIAL_SCALE_STYLE_LINE);
					arcChart.setScaleStyle(TWaverConst.DIAL_SCALE_STYLE_LINE);
				}
			}
		});
		stylePanel.add(scaleSytle, "1,0,1,0");

		stylePanel.add(createJLabel("Scale Inside:"), "0," + 1 + ",0," + 1);
		final JComboBox isInside = new JComboBox();
		isInside.addItem("Inside");
		isInside.addItem("Outside");
		isInside.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (isInside.getSelectedItem().toString().equals("Inside")) {
					wholeChart.setScaleInside(true);
					arcChart.setScaleInside(true);
				}
				else {
					wholeChart.setScaleInside(false);
					arcChart.setScaleInside(false);
				}
			}
		});
		isInside.setSelectedIndex(1);
		isInside.setSelectedIndex(0);
		stylePanel.add(isInside, "1,1,1,1");

		panel.add(stylePanel, "0," + rowIndex + ",2," + rowIndex);
		rowIndex++;

		return panel;
	}

	public JPanel createElementControlPanel() {
		double[] rows = new double[2];
		for (int i = 0; i < rows.length; i++) {
			rows[i] = TableLayout.PREFERRED;
		}
		double[] cols = new double[] { TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED };
		JPanel panel = new JPanel(new TableLayout(cols, rows, 10, 10));
		panel.setBorder(BorderFactory.createTitledBorder("Element Value"));
		int row = 0;

		panel.add(createJLabel("Hand Length:"), "0," + row + ",0," + row);
		final JTextField hanLengthTextfield = createJTextField();
		final JSlider handLengthSlider = createSlider(0, 100);
		handLengthSlider.addChangeListener(new ChangeListener() {
			public void stateChanged(ChangeEvent e) {
				element.putChartDialHandLength(handLengthSlider.getValue() / 100d);
				hanLengthTextfield.setText(handLengthSlider.getValue() / 100d + "");
			}
		});
		handLengthSlider.setValue((int) (element.getChartDialHandLength() * 100));
		hanLengthTextfield.setText(handLengthSlider.getValue() / 100d + "");
		panel.add(handLengthSlider, "1," + row + ",1," + row);
		panel.add(hanLengthTextfield, "2," + row + ",2," + row);
		row++;

		rows = new double[2];
		for (int i = 0; i < rows.length; i++) {
			rows[i] = TableLayout.PREFERRED;
		}
		cols = new double[] { TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED };
		JPanel stylePanel = new JPanel(new TableLayout(cols, rows, 10, 10));

		stylePanel.add(createJLabel("Hand Style:"), "0," + 0 + ",0," + 0);
		final JComboBox handSytle = new JComboBox();
		handSytle.addItem("Line");
		handSytle.addItem("Triangle");
		handSytle.addItem("Arrow");
		handSytle.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if (handSytle.getSelectedItem().toString().equals("Line")) {
					element.putChartDialHandStyle(TWaverConst.DIAL_HAND_STYLE_LINE);
				}
				else if (handSytle.getSelectedItem().toString().equals("Triangle")) {
					element.putChartDialHandStyle(TWaverConst.DIAL_HAND_STYLE_TRIANGLE);
				}
				else {
					element.putChartDialHandStyle(TWaverConst.DIAL_HAND_STYLE_ARROW);
				}
			}
		});
		handSytle.setSelectedItem("Triangle");
		stylePanel.add(handSytle, "1,0,1,0");

		stylePanel.add(createJLabel("Element Color:"), "0,1,0,1");
		final JButton button = new JButton("color");
		button.setBackground(element.getChartColor());
		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Color oldColor = element.getChartColor();
				String title = TWaverUtil.getString("ElementColor");
				Color selectedColor = JColorChooser.showDialog(DialChartDemo.this, title, oldColor);
				if (selectedColor != null) {
					element.putChartColor(selectedColor);
					button.setBackground(element.getChartColor());
				}
			}
		});
		stylePanel.add(button, "1,1,1,1");

		panel.add(stylePanel, "0," + row + ",1," + row);
		row++;

		return panel;
	}

	public void changeElementValue() throws Exception {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				double value = element.getChartValue();
				if (isplus == true) {
					value += 1;
					if (value > wholeChart.getMaxValue()) {
						value = wholeChart.getMaxValue();
						isplus = false;
					}
				} else {
					value -= 1;
					if (value < wholeChart.getMinValue()) {
						value = wholeChart.getMinValue();
						isplus = true;
					}
				}
				element.putChartValue(value);
			}
		});
	}

	public JSlider createSlider(int min, int max) {
		JSlider slider = new JSlider(min, max);
		return slider;
	}

	public JLabel createJLabel(String text) {
		JLabel label = new JLabel(text);
		label.setHorizontalAlignment(JLabel.RIGHT);
		return label;
	}

	public JTextField createJTextField() {
		JTextField textField = new JTextField(3);
		textField.setEditable(false);
		textField.setHorizontalAlignment(JLabel.RIGHT);
		return textField;
	}
}